"use strict";
import { app, protocol, BrowserWindow, ipcMain, Menu } from "electron";
import * as urllib from 'urllib'
import init, { Portweb } from './main/home'
// import update from "./main/uploader";
import { ipctype } from "./main/interface";
import { gesture, getface, recognize } from "./main/aip";
import { jsjiaodu, classname } from "./utils/port";
import savefile from "./utils/savefile";
import { ChildProcessWithoutNullStreams } from "child_process";
const isDevelopment = process.env.NODE_ENV !== "production";

// app.commandLine.appendSwitch("ignore-gpu-blacklist", "true");
// app.commandLine.appendSwitch("enable-zero-copy", "true");
// app.commandLine.appendSwitch("disable-software-rasterizer", "false");
// app.commandLine.appendSwitch("enable-native-gpu-memory-buffers", "true");
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow: BrowserWindow | null = null

// Standard scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
  { scheme: "app", privileges: { secure: true, standard: true } }
]);
const load = process.env.WEBPACK_DEV_SERVER_URL
// Quit when all windows are closed.
app.on("window-all-closed", () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== "darwin") {
    app.quit();
  }
});


const isMac = process.platform === 'darwin'

const template = [
  // { role: 'appMenu' }
  ...(isMac ? [{
    label: app.name,
    submenu: [
      { role: 'about' },
      { type: 'separator' },
      { role: 'services' },
      { type: 'separator' },
      { role: 'hide' },
      { role: 'hideothers' },
      { role: 'unhide' },
      { type: 'separator' },
      { role: 'quit' }
    ]
  }] : []),
  // { role: 'fileMenu' }
  {
    label: 'File',
    submenu: [
      isMac ? { role: 'close' } : { role: 'quit' }
    ]
  },
  // { role: 'editMenu' }
  {
    label: 'Edit',
    submenu: [
      { role: 'undo' },
      { role: 'redo' },
      { type: 'separator' },
      { role: 'cut' },
      { role: 'copy' },
      { role: 'paste' },
      ...(isMac ? [
        { role: 'pasteAndMatchStyle' },
        { role: 'delete' },
        { role: 'selectAll' },
        { type: 'separator' },
        {
          label: 'Speech',
          submenu: [
            { role: 'startspeaking' },
            { role: 'stopspeaking' }
          ]
        }
      ] : [
          { role: 'delete' },
          { type: 'separator' },
          { role: 'selectAll' }
        ])
    ]
  },
  // { role: 'viewMenu' }
  {
    label: 'View',
    submenu: [
      { role: 'reload' },
      { role: 'forcereload' },
      { role: 'toggledevtools' },
      { type: 'separator' },
      { role: 'resetzoom' },
      { role: 'zoomin' },
      { role: 'zoomout' },
      { type: 'separator' },
      { role: 'togglefullscreen' }
    ]
  },
  // { role: 'windowMenu' }
  {
    label: 'Window',
    submenu: [
      { role: 'minimize' },
      { role: 'zoom' },
      ...(isMac ? [
        { type: 'separator' },
        { role: 'front' },
        { type: 'separator' },
        { role: 'window' }
      ] : [
          { role: 'close' }
        ])
    ]
  },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click: async () => {
          const { shell } = require('electron')
          await shell.openExternal('https://electronjs.org')
        }
      }
    ]
  }
] as any

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)



// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === "win32") {
    process.on("message", data => {
      if (data === "graceful-exit") {
        app.quit();
      }
    });
  } else {
    process.on("SIGTERM", () => {
      app.quit();
    });
  }
} else {

}


async function createWindow() {
  init()
  mainWindow = new BrowserWindow({
    width: 1024,
    height: 600,
    show: false,
    title: '控制中心',
    fullscreen: true,
    backgroundColor: "#000000",
    webPreferences: {
      nodeIntegrationInWorker: true,
      nodeIntegration: true,
    }
  });

  if (process.env.NODE_ENV !== 'development') {

    mainWindow.loadFile(`./dist/index.html`)
  } else {
    mainWindow.loadURL(`${load}`)
  }

  mainWindow.once('ready-to-show', () => {
    mainWindow?.show()
    mainWindow?.maximize()

    // update().then(res => {
    //   if (res) {
    //     dialog.showMessageBox({
    //       type: 'info',
    //       title: '有新版本',
    //       message: '现在需要更新吗',
    //       buttons: ['更新', '不更新']
    //     }).then(res => {
    //       if (res) {
    //         shell.openExternal('https://www.hterobot.com')
    //       }
    //     })

    //   }
    // })
  })
}


app.on("ready", () => {
  if (mainWindow === null) {
    createWindow();
  }
});


app.on("quit", () => {
  // 关闭时检测是否是强制更新
  mainWindow = null
});

let str = ''

ipcMain.on(ipctype["baidu-gesture"], async (event, arg, type) => {
  let x = Date.now()
  let error = ''
  if (type === 'head') {
    let name = ''
    let data: any = { result: [] }
    try {
      data = await gesture(arg)
      x = Date.now() - x
    } catch ({ errorType }) {
      if (errorType === 'ERRTYPE_NETWORK') {
        error = '超时'
      }
      x = Date.now() - x
    }
    const result = data.result

    if (result?.length) {
      for (let v of result) {
        console.log(v.classname)
        if (v.classname === 'Face' || v.classname === 'Other') {

        } else {
          name = v.classname.toLocaleLowerCase()
        }
      }
      for (let v in classname) {
        v = v.toLocaleLowerCase()
        if (name && name.includes(v)) {
          str = classname[v]
          str = str + ',50,z'
          break;
        }
      }
    }
    event.sender.send(ipctype['change-head'], null, str, name, null, error ? error : x)
  } else {
    let data: any = { result: [] }
    try {
      data = await getface(arg)
      x = Date.now() - x
    } catch (e) {
      const { errorType } = e
      if (errorType === 'ERRTYPE_NETWORK') {
        error = '超时'
      }
      x = Date.now() - x
    }
    const result = data.face_list || []
    // let name = ''
    if (result?.length) {
      const { left } = result[0].location
      const p = 100 - Math.floor(left / 300 * 100)
      if (str.length) {
        const tmp = str.split(',')
        if (tmp.length === 7) {
          tmp[5] = String(p)
          str = tmp.join(',')
        } else {
          str = classname['five'] + ',' + p + ',z'
        }
      } else {
        str = classname['five'] + ',' + p + ',z'
      }
      event.sender.send(ipctype['change-head'], null, str, null, null, error ? error : x)
    } else {
      event.sender.send(ipctype['change-head'], null, str, null, null, error ? error : x)
    }
  }
})

ipcMain.on(ipctype['audio-buffer'], async (event, arg) => {
  let x = Date.now()
  let error = ''
  let data: any = { result: [] }
  try {
    data = await recognize(arg)
    x = Date.now() - x
  } catch ({ errorType }) {
    if (errorType === 'ERRTYPE_NETWORK') {
      error = '超时'
    }
    x = Date.now() - x
  }
  const result = data.result || []
  let key1 = ''
  let name = ''
  if (result?.length) {
    name = result[0]
    let [a, b] = jsjiaodu(name ? name : '')
    str = a
    key1 = b
  }
  if (str) {
    str = str + ',50,z'
  }
  event.sender.send(ipctype['change-head'], null, str, key1, name, error ? error : x)
})

ipcMain.on('fullscreen', function () {
  if (mainWindow) {
    mainWindow.setFullScreen(!mainWindow.isFullScreen())
  }
})


ipcMain.on(ipctype['savefile'], async (_event, xml, python) => {
  if (mainWindow) {
    savefile(mainWindow, xml, python)
  }
})
let up = false
ipcMain.on('up', (event, data: string) => {
  if (up) {
    event.returnValue = false
    return
  }
  up = true
  urllib.request(data).then(({ data }) => {
    const { version } = JSON.parse(data.toString())
    event.returnValue = version
  }).catch(() => {
    event.returnValue = false
  })
})


let ls: ChildProcessWithoutNullStreams | null = null

ipcMain.on('portweb', (_event, f: boolean) => {
  console.log(f)
  if (f && !ls) {
    ls = null
    Portweb().then(e => {
      ls = e
    }).catch(e => {
      console.log(e)
    })
  } else {
    ls?.kill()
    ls = null
  }
})




